package com.jz.netthings.utils;

import org.apache.tomcat.util.codec.binary.Base64;
import org.jdom2.Element;

import java.util.*;

public class XmlHelper {


    public static Object readValueTagHasType(Element tagParent, String tagName)
            throws Exception {
        Element element = tagParent.getChild(tagName);
        if (element != null) {
            return readValueHasType(element);
        }
        return null;
    }

    public static Object readValueHasType(Element element)
            throws Exception {
        String typeClass = element.getAttributeValue("type");
        if (typeClass != null && !"".equals(typeClass)) {
            if ("HashMap".equals(typeClass)) {
                HashMap<String, Object> v = new HashMap();
                for (Iterator<?> i = element.getChildren().iterator(); i.hasNext(); ) {
                    Element item = (Element) i.next();
                    Object itemValue = readValueHasType(item);
                    v.put(item.getName(), itemValue);
                }
                return v;
            }
            if ("List".equals(typeClass)) {
                List<Object> v = new ArrayList();
                for (Iterator<?> i = element.getChildren().iterator(); i.hasNext(); ) {
                    Element item = (Element) i.next();
                    Object itemValue = readValueHasType(item);
                    if (itemValue != null) {
                        v.add(itemValue);
                    }
                }
                return v;
            }
            String v = element.getTextTrim();
            if ("String".equals(typeClass)) {
                return element.getTextTrim();
            }
            if ("Boolean".equals(typeClass)) {
                return Boolean.valueOf("true".equals(v));
            }
            if ("Double".equals(typeClass)) {
                return new Double(Double.parseDouble(v));
            }
            if ("Float".equals(typeClass)) {
                return new Float(Float.parseFloat(v));
            }
            if ("Integer".equals(typeClass)) {
                return new Integer(Integer.parseInt(v));
            }
            if ("Long".equals(typeClass)) {
                return new Long(Long.parseLong(v));
            }
            if ("Short".equals(typeClass)) {
                return new Short(Short.parseShort(v));
            }
            if ("Byte".equals(typeClass)) {
                return new Byte(Byte.parseByte(v));
            }
            if ("Date".equals(typeClass)) {
                return DateUnit.toDate(v);
            }
            if ("byte[]".equals(typeClass)) {
                return Base64.decodeBase64(v.getBytes());
            }
            throw new Exception("xmlHelper遇到无法处理的数据类型(" + typeClass + ")");
        }
        throw new Exception("xmlHelper遇到无法处理的数据类型(空)");

    }


    public static void writeValueTagHasType(Element tagParent, String tagName, Object v)
            throws Exception
    {
        if (v != null)
        {
            Element element = new Element(tagName);
            tagParent.addContent(element);
            writeValueHasType(element, v);
        }
    }

    public static void writeValueHasType(Element element, Object v)
            throws Exception
    {
        if (v != null) {
            if ((v instanceof String))
            {
                element.setAttribute("type", "String");
                element.addContent((String)v);
            }
            else if ((v instanceof Boolean))
            {
                element.setAttribute("type", "Boolean");
                if (((Boolean)v).booleanValue()) {
                    element.addContent("true");
                } else {
                    element.addContent("false");
                }
            }
            else if ((v instanceof Double))
            {
                element.setAttribute("type", "Double");
                element.addContent(((Double)v).toString());
            }
            else if ((v instanceof Float))
            {
                element.setAttribute("type", "Float");
                element.addContent(((Float)v).toString());
            }
            else if ((v instanceof Integer))
            {
                element.setAttribute("type", "Integer");
                element.addContent(((Integer)v).toString());
            }
            else if ((v instanceof Long))
            {
                element.setAttribute("type", "Long");
                element.addContent(((Long)v).toString());
            }
            else if ((v instanceof Short))
            {
                element.setAttribute("type", "Short");
                element.addContent(((Short)v).toString());
            }
            else if ((v instanceof Byte))
            {
                element.setAttribute("type", "Byte");
                element.addContent(((Byte)v).toString());
            }
            else if ((v instanceof Date))
            {
                element.setAttribute("type", "Date");
                element.addContent(DateUnit.toText((Date)v));
            }
            else if ((v instanceof byte[]))
            {
                element.setAttribute("type", "byte[]");
                byte[] bs = Base64.encodeBase64((byte[])v);
                element.addContent(new String(bs));
            }
            else if ((v instanceof HashMap))
            {
                if (!((HashMap)v).isEmpty())
                {
                    element.setAttribute("type", "HashMap");
                    Set<Map.Entry> entrySet = ((HashMap)v).entrySet();
                    for (Iterator<Map.Entry> i = entrySet.iterator(); i.hasNext();)
                    {
                        Map.Entry entry = (Map.Entry)i.next();
                        writeValueTagHasType(element, entry.getKey().toString(), entry.getValue());
                    }
                }
            }
            else if ((v instanceof List))
            {
                if (!((List)v).isEmpty())
                {
                    element.setAttribute("type", "List");
                    for (Iterator<?> i = ((List)v).iterator(); i.hasNext();) {
                        writeValueTagHasType(element, "DataItem", i.next());
                    }
                }
            }
            else
            {
                throw new Exception("xmlHelper遇到无法处理的数据类型(" + v.getClass().getSimpleName() + ")");
            }
        }
    }
}
